#include <boost/lexical_cast.hpp>

#include "include/ModelProxy.h"


ModelProxy::~ModelProxy()
{
	_memcache_proxy.Exit();
}

void ModelProxy::Init()
{
	_mysql_proxy.Init();
	_memcache_proxy.Init();
}

int ModelProxy::BeginTransaction()
{
	return _mysql_proxy.BeginTransaction();
}

void ModelProxy::BreakTransaction()
{
	_mysql_proxy.RollBack();
}

void ModelProxy::EndTransaction()
{
	_mysql_proxy.Commit();
}

int ModelProxy::GetObjectById(string table_name, string id_name, int id_value, string &value)
{
	string str = boost::lexical_cast<string>(id_value);
	return GetObjectById(table_name, id_name, str, value);
}

int ModelProxy::GetObjectById(string table_name, string id_name, string id_value, string &value)
{
	string key = table_name + "_" + id_name + "_" + id_value;

	// test
	cout << "before query, key: " << key << endl;

	if(!_memcache_proxy.GetDbValue(key, value))
	{
	    return 0;
	}

    // test
    cout << "no result in memcache!" << endl;

    mysqlpp::StoreQueryResult res = _mysql_proxy.SelectItemByID(table_name, id_name, id_value);
    if(_mysql_proxy.IsQueryError())
    {
        cout << "query error" << endl;
        return 1;
    }

    if(_mysql_proxy.SingleRes2StdString(res, value, '|'))
    {
        cout << "SingleRes2StdString error!" << endl;
        return 1;
    }

    _memcache_proxy.SetDbValue(key, value);

	return 0;
}

int ModelProxy::InsertObject(string table_name, string &value)
{
	return _mysql_proxy.Exec("insert into " + table_name + value);
}

int ModelProxy::ReplaceObject(string table_name, string &value)
{
    cout << "replace sql: " << table_name << value << endl;

	return _mysql_proxy.Exec("replace into " + table_name + value);
}

int ModelProxy::ReplaceObjectById(string table_name, string id_name, int id_value, string &value)
{
	_memcache_proxy.RemoveDbValue(table_name + "_" + id_name + "_" + boost::lexical_cast<string>(id_value));

    return ReplaceObject(table_name, value);
}

int ModelProxy::ReplaceMemcacheObject(string key, string &value)
{
	string old_value;
	if(!_memcache_proxy.GetMemValue(key, old_value))
	{
		_memcache_proxy.RemoveMemValue(key);
	}

	return _memcache_proxy.SetMemValue(key, value, 0);
}

int ModelProxy::GetMemcacheObject(string key, string &value)
{
	return _memcache_proxy.GetMemValue(key, value);
}

int ModelProxy::SetMemcacheObject(string key, string &value)
{
	return _memcache_proxy.SetMemValue(key, value);
}

int ModelProxy::DelMemcacheObject(string key)
{
	return _memcache_proxy.RemoveMemValue(key);
}

int ModelProxy::GetObjectBySql(string key, string &sql, string &value)
{
	if(!_memcache_proxy.GetDbValue(key, value))
	{
	    return 0;
	}

    mysqlpp::StoreQueryResult res = _mysql_proxy.DoQuery(sql);
    if(_mysql_proxy.IsQueryError())
    {
        cout << "query error" << endl;
        return 1;
    }

    _mysql_proxy.MultiRes2StdString(res, value, '|', '_');

    if(value != "")
    {
        _memcache_proxy.SetDbValue(key, value, 0);
    }

	return 0;
}

string ModelProxy::GetSingleStrBySql(string &sql)
{
    mysqlpp::StoreQueryResult res = _mysql_proxy.DoQuery(sql);
    if(_mysql_proxy.IsQueryError())
    {
        cout << "query error" << endl;
        return "";
    }

    return res[0][0].c_str();
}
